package com.theyeasy.dvmini.socket;

import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.theyeasy.dvmini.model.WebSockMsg;
import com.theyeasy.dvmini.service.DvminiSocketService;
import com.theyeasy.dvmini.util.QQFaceUtil;

public class PcWebSocketHandler implements WebSocketHandler {

	private static Logger log = LoggerFactory.getLogger(PcWebSocketHandler.class);

	private static final Map<String, Map<Integer, WebSocketSession>> userMap;

	@Autowired
	DvminiSocketService dvminiSocketService;
	@Autowired
	RedisTemplate<String, Integer> redisTemplate;

	static {
		userMap = new HashMap<String, Map<Integer, WebSocketSession>>();
	}

	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		String roomId = getRoomId(session);
		Integer fromId = getFromId(session);
		if (!Strings.isNullOrEmpty(roomId)) {
			Map<Integer, WebSocketSession> userSocket = null;
			if (userMap.containsKey(roomId)) {
				userSocket = userMap.get(roomId);
			} else {
				userSocket = Maps.newHashMap();
			}
			userSocket.put(fromId, session);
			userMap.put(roomId, userSocket);
		}

		if (roomId.equals("0")) {
			redisTemplate.boundSetOps(DvminiSocketService.KEY_VANKER).add(fromId);
		} else {
			redisTemplate.boundSetOps(DvminiSocketService.KEY_SALES).add(fromId);
		}

	}

	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
		try {
			String payload = ((TextMessage) message).getPayload();
			final WebSockMsg msg = WebSockMsg.fromJson(payload);
			if (msg.isReaded()) {
				msg.setAsktime(new Date());
				String ask = msg.getAsk();
				String reply = msg.getReply();
				msg.setReply(QQFaceUtil.regix(reply));
				msg.setAsk(QQFaceUtil.regix(ask));
				session.sendMessage(new TextMessage(msg.toJson()));
			}
			dvminiSocketService.recevice(msg);

		} catch (Exception e) {
			e.printStackTrace();
			session.sendMessage(new TextMessage("消息处理异常"));
		}
	}

	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		try {
			webSocketSessionClosed(session, 1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		try {
			webSocketSessionClosed(session, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public boolean supportsPartialMessages() {
		return false;
	}

	/**
	 * 发消息给在线用户
	 * 
	 * @param message
	 */
	public static void sendMessageToRandomVankor(TextMessage message, int idex) {
		Map<Integer, WebSocketSession> map = userMap.get("0");
		if (map == null || map.isEmpty()) {
			return;
		}
		Set<Entry<Integer, WebSocketSession>> entrySet = map.entrySet();
		Iterator<Entry<Integer, WebSocketSession>> iterator = entrySet.iterator();
		WebSocketSession next = iterator.next().getValue();
		if (next.isOpen()) {
			try {
				next.sendMessage(message);
			} catch (IOException e1) {
				e1.printStackTrace();
				if (idex != 0) {
					sendMessageToRandomVankor(message, idex--);
				}

			}
		}

	}

	/**
	 * 发消息给某个用户
	 */
	public static void sendToOne(TextMessage message, String rid, Integer uid) {
		Map<Integer, WebSocketSession> map = userMap.get(rid);
		if (map != null)
			map.forEach((K, V) -> {
				if (K.intValue() == uid) {
					if (V.isOpen()) {
						try {
							V.sendMessage(message);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			});

	}

	/**
	 * 获取网址路径中的uniqueid
	 * 
	 * @param uri
	 *            网址Uri
	 * @return
	 */
	private String getRoomId(WebSocketSession session) {
		URI uri = session.getUri();
		String path = uri.getPath();
		if (!Strings.isNullOrEmpty(path)) {
			String[] paths = path.split("/");
			String uuid = paths[paths.length - 1];
			return uuid;
		} else {
			return "";
		}
	}

	private static Integer getFromId(WebSocketSession session) {
		URI uri = session.getUri();
		String path = uri.getPath();
		try {
			if (!Strings.isNullOrEmpty(path)) {
				String[] paths = path.split("/");
				String uid = paths[paths.length - 2];
				return Integer.parseInt(uid);
			}
		} catch (Exception e) {
		}
		return 0;

	}

	/**
	 * 关闭WebSocketSession
	 * 
	 * @param session
	 * @param type
	 *            1异常关闭 0 正常关闭
	 * @throws IOException
	 */
	private void webSocketSessionClosed(WebSocketSession session, int type) throws IOException {
		if (type == 1) {
			if (session.isOpen()) {
				try {
					session.close();
				} catch (Exception e) {
				}
			}

		}
		if (getRoomId(session).equals("0")) {
			redisTemplate.boundSetOps(DvminiSocketService.KEY_VANKER).remove(getFromId(session));
		} else {
			redisTemplate.boundSetOps(DvminiSocketService.KEY_SALES).remove(getFromId(session));
		}
		try {
			userMap.get(getRoomId(session)).remove(getRoomId(session));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static Map<String, Map<Integer, WebSocketSession>> getUsermap() {
		return userMap;
	}

}
